#include "blockqueue.hpp"
#include "task.hpp"
#include <time.h>
#include <unistd.h>


void* consumer(void* args)
{
    //BlockQueue<int>* bq = static_cast<BlockQueue<int>*>(args);
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);
    
    while(1)
    {
        //sleep(1);//阻塞队列先被放满数据，之后消费者每次从里面拿走一个数据，拿走的同时，生产者就会放入新的数据
        //int data = 0;
        //bq->pop(&data);
        Task t;
        bq->pop(&t);
        t();
        std::cout << "consumer pop : " << t.formatArg() << t.formatRes() << std::endl;
    }
}

void* productor(void* args)
{
    BlockQueue<Task>* bq = static_cast<BlockQueue<Task>*>(args);

    while(1)
    {
        sleep(1); //这里加上sleep之后，就是每秒生产一个数据，并且每生产出来一个数据就会被消费者进程拿走
        //int n = rand()%10+1;
        //bq->push(n);
        std::string str = "+-*/%";
        int x = rand()%10;
        int y = rand()%10;
        char op = str[rand()%str.size()];//每次随机取一个运算符
        Task t(x, y, op);
        bq->push(t);
        std::cout << "produtor push : " << t.formatArg() << "?" <<std::endl;
    }
}

int main()
{
    srand((uint64_t)time(nullptr));
    BlockQueue<Task>* bq = new BlockQueue<Task>();

    //单生产和单消费
    // pthread_t t1, t2;
    // pthread_create(&t1, nullptr, consumer, bq);
    // pthread_create(&t1, nullptr, productor, bq);

    // pthread_join(t1, nullptr);
    // pthread_join(t2, nullptr);

    //多生产和多消费
    pthread_t c[2], p[3];
    pthread_create(&c[0], nullptr, consumer, bq);
    pthread_create(&c[1], nullptr, consumer, bq);
    pthread_create(&p[0], nullptr, productor, bq);
    pthread_create(&p[1], nullptr, productor, bq);
    pthread_create(&p[2], nullptr, productor, bq);

    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
    pthread_join(p[2], nullptr);
    
    delete bq;
    return 0;
}